package com.ihr360.payroll.model.dto.salary.payslip;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ihr360.authority.sharing.model.IResourceControl;
import com.ihr360.authority.sharing.model.ResourceAccess;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.hibernate.type.encrypt.JsonEncryptType;
import com.ihr360.payroll.model.dto.salary.payslip.embeddable.HeadCell;
import com.ihr360.payroll.model.dto.salary.payslip.embeddable.PayslipHeadSnapshot;
import com.ihr360.payroll.model.dto.salary.plan.config.PayslipConfig;
import com.ihr360.payroll.model.dto.salary.report.HistoryPayPeriod;
import com.ihr360.payroll.model.dto.salary.task.period.StaffPayPeriodTermSalary;
import com.ihr360.payroll.model.vo.PayslipStaffSalaryVo;
import com.ihr360.shared.entitywithlistener.NumberIdWithTimeAndCompanyId;
import com.vladmihalcea.hibernate.type.json.JsonStringType;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author tomtao
 */
@TypeDefs({
        @TypeDef(name = "json", typeClass = JsonStringType.class),
        @TypeDef(name = "json-encrypt", typeClass = JsonEncryptType.class)
})
@Getter
@Setter
@Entity
public class PayslipResult extends NumberIdWithTimeAndCompanyId<Long> implements IResourceControl {

    private static final long serialVersionUID = 4580357257045515746L;

    public class PayslipStatus {
        public final static int DEFAULT = 0;
        public final static int PUBLISH = 1;
    }

    /**
     * 工资单表头快照
     */
    @Column(columnDefinition = "text", name = "payslipHead")
    @Type(type = "json")
    private PayslipHeadSnapshot payslipHeadSnapshot;

    @OneToOne
    private PayslipConfig payslip;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "payslipResult")
    private List<StaffPayslip> staffPayslipList;

    @ManyToOne
    @JoinColumn(name = "historyPayPeriod_id")
    private HistoryPayPeriod payPeriod;

    @Column(columnDefinition = "bit(1) default 0")
    private int status = PayslipStatus.DEFAULT;

    private Date publishedAt;

    @Embedded
    private ResourceAccess resourceAccess;

    @Override
    public ResourceAccess getResourceAccess() {
        if (resourceAccess == null) {
            resourceAccess = new ResourceAccess();
        }
        return resourceAccess;
    }

    @Override
    public void setResourceAccess(ResourceAccess resourceAccess) {
        this.resourceAccess = resourceAccess;
    }

    @JsonIgnore
    public Long getSalaryPlanId() {
        return payPeriod.getSalaryPlan().getSalaryPlanId();
    }

    @JsonIgnore
    public int getYear() {
        return payPeriod.getYear();
    }

    @JsonIgnore
    public int getMonth() {
        return payPeriod.getMonth();
    }

    @JsonIgnore
    public String getPayslipConfigName() {
        return payslip == null ? null : payslip.getName();
    }

    @JsonIgnore
    public Long getPayslipConfigId() {
        return payslip == null ? null : payslip.getId();
    }

    @JsonIgnore
    public String getStatusName() {
        if (status == PayslipStatus.DEFAULT) {
            return "未发布";
        } else if (status == PayslipStatus.PUBLISH) {
            return "发布";
        }
        return "错误代码";
    }

    @JsonIgnore
    public int getStaffNum() {
        return staffPayslipList.size();
    }

    @JsonIgnore
    public List<PayslipStaffSalaryVo> getStaffSalaryListVo() {
        if (CollectionUtils.isEmpty(staffPayslipList)) {
            return Collections.emptyList();
        }
        List<PayslipStaffSalaryVo> staffSalaryVos = new ArrayList<>();
        staffPayslipList.forEach(staffPayslip -> {
            StaffPayPeriodTermSalary staffSalary = staffPayslip.getStaffSalary();
            PayslipStaffSalaryVo payslipStaffSalaryVo = new PayslipStaffSalaryVo(staffSalary.getStaffName(), staffSalary.getMobileNo(), staffSalary.getDepartmentName(),
                    staffSalary.getYear(), staffSalary.getMonth(), staffSalary.getSalaryDynamicCell());
            staffSalaryVos.add(payslipStaffSalaryVo);
        });
        return staffSalaryVos;
    }

    @JsonIgnore
    public Map<String, String> getHeadMap() {
        Map<String, String> headMap = new LinkedHashMap<>();
        if (payslipHeadSnapshot == null) {
            return headMap;
        }
        for (HeadCell headCell : payslipHeadSnapshot.getHeadCellList()) {
            headMap.put(headCell.getCode(), headCell.getDisplayName());
        }
        return headMap;
    }

}
